#include "Camera.h"
#include <cassert>
#include <cmath>

using namespace RayTrace;
CCamera::CCamera(void)
{
}

CCamera::~CCamera(void)
{
}

void RayTrace::CCamera::Set( const vector3& eye, const vector3& up, const vector3& center, float near, float ratio, float fovy )
{
	mEye=eye;
	mUp=up;
	mCenter=center;
	mNear=near;
	mRatio=ratio;
	mFovy=fovy;

	vector3 dirt=(center-eye).Normalize();
	float t=vector3::Dot(up,dirt);
	vector3 normalup;
	if (t>MMIN){
		float b=vector3::Dot(dirt,dirt)/t;
		normalup=b*up-dirt;
	}
	else if (t<-(MMIN))
	{
		float b=(-1.0f*vector3::Dot(dirt,dirt))/t;
		normalup=(b*up+dirt);
	}
	else{
		normalup=up;
	}
	float debug=vector3::Dot(normalup,dirt);
	assert(fabs(debug)<MMIN);

	
	vector3 screenPoint=dirt*near+eye;
	double h=tan((fovy/180)*3.1415926*0.5)*near;
	vector3 wBias=vector3::Cross(dirt,normalup).Normalize()*h*ratio;
	vector3 hBias=normalup.Normalize()*(h);
	mProjScreen.topLeft=screenPoint+hBias-wBias;
	mProjScreen.topRight=screenPoint+hBias+wBias;
	mProjScreen.bottomLeft=screenPoint-hBias-wBias;
	mProjScreen.bottomRight=screenPoint-hBias+wBias;
}

const Screen & RayTrace::CCamera::GetScreen() const
{
	return mProjScreen;
}

const vector3& RayTrace::CCamera::GetEyePoint() const
{
	return mEye;
}